﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace iseeqq
{
    class WindowTools
    {

        //获取托盘指针 
        public static IntPtr TrayToolbarWindow32()
        {
            IntPtr h = IntPtr.Zero;
            IntPtr hTemp = IntPtr.Zero;

            h = Win32API.FindWindow("Shell_TrayWnd", null); //托盘容器 
            h = Win32API.FindWindowEx(h, IntPtr.Zero, "TrayNotifyWnd", null);//找到托盘 
            h = Win32API.FindWindowEx(h, IntPtr.Zero, "SysPager", null);

            hTemp = Win32API.FindWindowEx(h, IntPtr.Zero, "ToolbarWindow32", null);

            return hTemp;
        }

        public static string getWindowText(IntPtr intptr)
        {
            StringBuilder s = new StringBuilder();
            Win32API.GetWindowText(intptr, s, s.Capacity);
            return s.ToString();
        }


        public static unsafe List<TrayInfo> GetTrayList()
        {

            List<TrayInfo> iconList = new List<TrayInfo>();
            IntPtr pid = IntPtr.Zero;
            IntPtr ipHandle = IntPtr.Zero; //图标句柄 
            IntPtr lTextAdr = IntPtr.Zero; //文本内存地址 

            IntPtr ipTray = TrayToolbarWindow32();

            iseeqq.Win32API.RECT rc = new iseeqq.Win32API.RECT();
            Win32API.GetWindowRect(ipTray, ref rc);

            Win32API.GetWindowThreadProcessId(ipTray, ref pid);
            if (pid.Equals(0)) return iconList;

            IntPtr hProcess = Win32API.OpenProcess(Win32API.PROCESS_ALL_ACCESS | Win32API.PROCESS_VM_OPERATION | Win32API.PROCESS_VM_READ | Win32API.PROCESS_VM_WRITE, IntPtr.Zero, pid);
            IntPtr lAddress = Win32API.VirtualAllocEx(hProcess, 0, 4096, Win32API.MEM_COMMIT, Win32API.PAGE_READWRITE);

            //得到图标个数 
            int lButton = Win32API.SendMessage(ipTray, Win32API.TB_BUTTONCOUNT, 0, 0);
            int width = (rc.Right - rc.Left) / lButton;

            byte[] buff, buffText;
            uint vNumberOfBytesRead = 0;
            for (int i = 0; i < lButton; i++)
            {
                //
                Win32API.SendMessage(ipTray, Win32API.TB_GETBUTTON, i, lAddress);
                TBBUTTON tbButton = new TBBUTTON();
                TBBUTTON* pTBButton = &tbButton;
                IntPtr ipTBButton = new IntPtr(pTBButton);
                Int32 dwBytesRead = 0;
                IntPtr ipBytesRead = new IntPtr(&dwBytesRead);

                //读句柄地址 
                IntPtr ipHandleAdr = IntPtr.Zero;
                Win32API.ReadProcessMemory(hProcess, (IntPtr)(lAddress.ToInt32() + 16), ref ipHandleAdr, 4, 0);
                Win32API.ReadProcessMemory(hProcess, ipHandleAdr, ref ipHandle, 4, 0);


                //读文本地址 
                buff = new byte[1024];
                bool b2 = Win32API.ReadProcessMemory(hProcess, lAddress, ipTBButton, new UIntPtr((uint)sizeof(TBBUTTON)), ipBytesRead);
                int c = Win32API.ReadProcessMemory(hProcess, tbButton.iString, buff, 1024, 0);//读文本 
                string title = System.Text.ASCIIEncoding.Unicode.GetString(buff);
                title = title.Substring(title.LastIndexOf("\\") + 1).Replace("\0", "");

                if (title.Contains("explorer.exe")) continue; //系统项，排除
                if (title.Contains("TeamViewer.exe")) continue; //系统项，排除

                //读 BUTTONTEXT
                buffText = new byte[1024];
                Win32API.SendMessage(ipTray, Win32API.TB_GETBUTTONTEXT, (IntPtr)tbButton.idCommand, lAddress);
                Win32API.ReadProcessMemory(hProcess, lAddress, Marshal.UnsafeAddrOfPinnedArrayElement(buffText, 0), buffText.Length * sizeof(char), ref  vNumberOfBytesRead);
                string tip = System.Text.ASCIIEncoding.Unicode.GetString(buffText);
                tip = tip.Substring(tip.LastIndexOf("\\") + 1).Replace("\0", "");

                iseeqq.Win32API.RECT wrect = new iseeqq.Win32API.RECT();
                wrect.Top = rc.Top;
                wrect.Bottom = rc.Bottom;
                wrect.Left = rc.Left + (i) * width;
                wrect.Right = wrect.Left + width;

                TrayInfo trayInfo = new TrayInfo();
                trayInfo.Title = title;
                trayInfo.Handle = ipHandle;
                trayInfo.pid = pid;
                trayInfo.Tect = wrect;
                trayInfo.Tip = tip;
                trayInfo.idCommand = tbButton.idCommand;
                iconList.Add(trayInfo);

            }
            Win32API.VirtualFreeEx(hProcess, lAddress, 4096, Win32API.MEM_RELEASE);
            Win32API.CloseHandle(hProcess);

            return iconList;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct TBBUTTON
        {
            public Int32 iBitmap;
            public Int32 idCommand;
            public byte fsState;
            public byte fsStyle;
            //      [ MarshalAs( UnmanagedType.ByValArray, SizeConst=2 ) ]
            //      public byte[] bReserved;
            public byte bReserved1;
            public byte bReserved2;
            public UInt32 dwData;

            public IntPtr iString;
        };

    }
}
